package com.ihrm.system.service;

import com.ihrm.common.utils.IdWorker;
import com.ihrm.domain.system.Role;
import com.ihrm.domain.system.User;
import com.ihrm.system.dao.RoleDao;
import com.ihrm.system.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

@Service
public class UserService {

    @Autowired
    UserDao userDao;

    @Autowired
    RoleDao roleDao;

    @Autowired
    IdWorker idWorker;

    /**
     * 1.保存用户
     */
    public void save(User user){
        String id = idWorker.nextId() + "";
        user.setId(id);
        user.setPassword("123456");
        user.setEnableState(1);
        user.setCreateTime(new Date());
        userDao.save(user);
    }

    /**
     * 2.更新用户
     */
    public void update(User user){
        User targetUser = userDao.findById(user.getId()).get();
        targetUser.setUsername(user.getUsername());
        targetUser.setPassword(user.getPassword());
        targetUser.setDepartmentId(user.getDepartmentId());
        targetUser.setDepartmentName(user.getDepartmentName());
        userDao.save(targetUser);
    }

    /**
     * 3.根据id查询用户
     */
    public User findById(String id){
        return userDao.findById(id).get();
    }

    /**
     * 4.查询全部用户列表
     *      参数：map集合的形式
     *          hasDept
     *          departmentId
     *          companyId
     *
     */
    public Page<User> findSearch(Map<String,Object> map, int page, int size){
        Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<>();
                //根据请求的companyId是否为空构造查询条件
                if(!StringUtils.isEmpty(map.get("companyId"))) {
                    list.add(criteriaBuilder.equal(root.get("companyId").as(String.class),(String)map.get("companyId")));
                }
                //根据请求的部门id构造查询条件
                if(!StringUtils.isEmpty(map.get("departmentId"))) {
                    list.add(criteriaBuilder.equal(root.get("departmentId").as(String.class),(String)map.get("departmentId")));
                }
                if(!StringUtils.isEmpty(map.get("hasDept"))) {
                    //根据请求的hasDept判断  是否分配部门 0未分配（departmentId = null），1 已分配 （departmentId ！= null）
                    if("0".equals((String) map.get("hasDept"))) {
                        list.add(criteriaBuilder.isNull(root.get("departmentId")));
                    }else {
                        list.add(criteriaBuilder.isNotNull(root.get("departmentId")));
                    }
                }
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };
        Page<User> userPage = userDao.findAll(specification, new PageRequest(page - 1, size));
        return userPage;
    }

    /**
     * 5.根据id删除用户
     */
    public void deleteById(String id){
        userDao.deleteById(id);
    }

    /**
     * 通过手机号码，密码验证用户
     * @param mobile
     * @param password
     * @return
     */
    public User findByMobileAndPassword(String mobile, String password){
        Optional<User> userOptional = userDao.findOne(createUserSpecification(mobile));
        boolean present = userOptional.isPresent();
        if(!present){
            return null;
        }
        User user = userOptional.get();
        if(password.equals(user.getPassword())){
            return user;
        }else{
            return null;
        }
    }

    public User findByMobile(String mobile){
        Optional<User> userOptional = userDao.findOne(createUserSpecification(mobile));
        boolean present = userOptional.isPresent();
        if(!present){
            return null;
        }
        return userOptional.get();
    }

    /**
     * 调整部门
     */
    public void changeDept(String deptId, String deptName, List<String> ids){
        for(String id : ids){
            User user = userDao.findById(id).get();
            user.setDepartmentId(deptId);
            user.setDepartmentName(deptName);
            userDao.save(user);
        }
    }

    /**
     * 分配角色
     */
    public void assignRoles(String userId, List<String> roleIds){
        User user = userDao.findById(userId).get();
        Set<Role> roles = new HashSet<>();
        for(String id : roleIds){
            Role role = roleDao.findById(id).get();
            roles.add(role);
        }
        user.setRoles(roles);
        userDao.save(user);
    }

    /**
     * 动态条件构建
     * @param searchMap
     * @return
     */
    private Specification<User> createSpecification(Map searchMap) {
        return new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query,
                                         CriteriaBuilder cb) {
                List<Predicate> predicateList = new ArrayList<Predicate>();
                // ID
                if (searchMap.get("id") !=null && !"".equals(searchMap.get("id"))) {
                    predicateList.add(cb.equal(root.get("id").as(String.class),
                            (String)searchMap.get("id")));
                }
                // 手机号码
                if (searchMap.get("mobile")!=null && !"".equals(searchMap.get("mobile"))) {
                    predicateList.add(cb.equal(root.get("mobile").as(String.class),
                            (String)searchMap.get("mobile")));
                }
                // 用户ID
                if (searchMap.get("departmentId")!=null && !"".equals(searchMap.get("departmentId"))) {
                    predicateList.add(cb.like(root.get("departmentId").as(String.class),
                            (String)searchMap.get("departmentId")));
                }
                // 标题
                if (searchMap.get("formOfEmployment")!=null && !"".equals(searchMap.get("formOfEmployment"))) {
                    predicateList.add(cb.like(root.get("formOfEmployment").as(String.class),
                            (String)searchMap.get("formOfEmployment")));
                }
                if (searchMap.get("companyId")!=null && !"".equals(searchMap.get("companyId"))) {
                    predicateList.add(cb.like(root.get("companyId").as(String.class),
                            (String)searchMap.get("companyId")));
                }
                if (searchMap.get("hasDept")!=null && !"".equals(searchMap.get("hasDept"))) {
                    if("0".equals((String)searchMap.get("hasDept"))) {
                        predicateList.add(cb.isNull(root.get("departmentId")));
                    }else{
                        predicateList.add(cb.isNotNull(root.get("departmentId")));
                    }
                }
                return cb.and( predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
    }

    private Specification<User> createUserSpecification(String mobile){
        return new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = criteriaBuilder.equal(root.get("mobile").as(String.class), mobile);
                return predicate;
            }
        };
    }
}
